package top.codedance.iotp.server.net.session;

import top.codedance.iotp.common.constent.CSession;
import cd.io.netty.channel.Channel;
import cd.io.netty.util.AttributeKey;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class SessionManager {
    private final ConcurrentHashMap<String, Session> channelMap = new ConcurrentHashMap<>();
    private final AttributeKey<String> key = CSession.sessionKey;

    /**
     * 设备上线
     *
     * @param channel
     * @param id
     */
    public void onLine(Channel channel, String id) {
        Session session = new Session();
        session.setChannel(channel);
        this.channelMap.put(id, session);
        channel.attr(key).set(id);
    }

    /**
     * 设备断线
     *
     * @param channel
     * @param id
     */
    public void offLine(Channel channel, String id) {
        if (channel != null) {
            channel.attr(key).remove();
            if (this.channelMap.containsKey(id)) {
                this.channelMap.remove(id);
            }
        }
    }

    /**
     * 依据设备id获取Session对象
     *
     * @param deviceId
     * @return
     */
    public Session getSessionByDeviceId(String deviceId) {
        Set<Map.Entry<String, Session>> entries = this.channelMap.entrySet();
        for (Map.Entry<String, Session> entity : entries) {
            Session value = entity.getValue();
            if (value.getDeviceId().equals(deviceId)) {
                return value;
            }
        }
        return null;
    }

    /**
     * 客户端注册设备id
     *
     * @param channel
     * @param deviceId
     */
    public Session registry(Channel channel, String deviceId, String clientPublicKey) {
        Session session = getSessionById(channel.id().toString());
        session.setClientPublicKey(clientPublicKey);
        session.setDeviceId(deviceId);
        return session;
    }

    /**
     * 获取session的数量
     *
     * @return
     */
    public int getSessionCount() {
        return this.channelMap.size();
    }

    /**
     * 获取所以注删客户端的设备ID列表
     *
     * @return
     */
    public String[] getClientDeviceIds() {
        List<String> resultList = new ArrayList<>();
        Set<Map.Entry<String, Session>> entries = channelMap.entrySet();
        for (Map.Entry<String, Session> entiry : entries) {
            String deviceId = entiry.getValue().getDeviceId();
            if (deviceId != null && !deviceId.equals("null")) {
                resultList.add(entiry.getValue().getDeviceId());
            }
        }
        String[] result = new String[resultList.size()];
        resultList.toArray(result);
        return result;
    }

    /**
     * 是否有这个AttrSession
     *
     * @param channel
     * @return
     */
    public boolean hasAttrSession(Channel channel) {
        return (channel.hasAttr(key) || channel.attr(key).get() != null); //netty移除了这个map的remove方法,这里的判断谨慎一点
    }

    /**
     * 通过channel id获取 Session对象
     *
     * @param id
     * @return
     */
    public Session getSessionById(String id) {
        return this.channelMap.get(id);
    }

    /**
     * 是否在线
     *
     * @param id
     * @return
     */
    public Boolean isOnline(String id) {
        String[] clientDeviceIds = getClientDeviceIds();
        List<String> strings = Arrays.asList(clientDeviceIds);
        return strings.contains(id);
    }
}
